{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "# Using ReliableTool to Generate Sub-Questions (Synchronous Version)\n",
    "This notebook demonstrates how to use the `ReliableTool` synchronously."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "from typing import Annotated\n",
    "\n",
    "from autogen import LLMConfig, config_list_from_json\n",
    "from autogen.tools.experimental.reliable import ReliableTool\n",
    "\n",
    "# Configure logging\n",
    "# Set level to DEBUG to see more internal details if needed\n",
    "# logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')\n",
    "logging.basicConfig(level=logging.INFO, format=\"%(asctime)s [%(levelname)s] %(name)s: %(message)s\")\n",
    "logger = logging.getLogger(__name__)\n",
    "\n",
    "print(\"Successfully imported components from autogen.\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "2",
   "metadata": {},
   "source": [
    "\n",
    "## 1. Define the Core Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_sub_questions_list(\n",
    "    sub_questions: Annotated[list[str], \"A list of sub-questions related to the main question.\"],\n",
    ") -> list[str]:\n",
    "    \"\"\"\n",
    "    Receives and returns a list of generated sub-questions.\n",
    "    \"\"\"\n",
    "    logger.info(f\"Core function received sub_questions: {sub_questions}\")\n",
    "    return sub_questions\n",
    "\n",
    "\n",
    "def grade_sub_question(\n",
    "    grade: Annotated[int, \"A grade for the sub_question.\"],\n",
    "    grade_justification: Annotated[str, \"A justification for the grade for the sub_question.\"],\n",
    ") -> tuple[int, str]:\n",
    "    \"\"\"\n",
    "    Used to grade a sub question.\n",
    "    \"\"\"\n",
    "    logger.info(f\"Core function received grade: {grade}\")\n",
    "    # Note, the left return value is just the grade!\n",
    "    return grade, f\"Grade: {grade} \\n Grade Justification: \\n {grade_justification}\""
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "4",
   "metadata": {},
   "source": [
    "## 2. Configure LLM and ReliableTool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm_config: LLMConfig | None = None\n",
    "try:\n",
    "    config_list = config_list_from_json(\n",
    "        \"OAI_CONFIG_LIST\",\n",
    "    )\n",
    "    llm_config = LLMConfig(\n",
    "        *config_list,\n",
    "        temperature=0.7,\n",
    "    )\n",
    "    print(f\"Using LLM config: {config_list[0].get('base_url', 'Default Endpoint')}, Model: {config_list[0]['model']}\")\n",
    "except Exception as e_config:\n",
    "    print(f\"Error creating LLM config: {e_config}. Tools cannot be initialized.\")\n",
    "    llm_config = None\n",
    "\n",
    "sub_question_system_message_addition_for_tool_calling = \"You are an assistant that helps break down questions. Your goal is to generate exactly 3 relevant sub-questions based on the main task. Use the provided `generate_sub_questions_list` tool to output the list you generate. Provide the generated list as the 'sub_questions' argument.\"\n",
    "sub_question_system_message_addition_for_result_validation = \"\"\"You are a quality control assistant. Your task is to validate the output received, which should be a list of sub-questions generated by another assistant.\n",
    "\n",
    "**Validation Criteria:**\n",
    "1.  **Correct Format:** The output MUST be a list of strings.\n",
    "2.  **Correct Quantity:** The list MUST contain exactly 3 sub-questions.\n",
    "3.  **Relevance:** Each sub-question MUST be clearly relevant to the original main question described in the initial task.\n",
    "\"\"\"\n",
    "\n",
    "sub_question_tool: ReliableTool | None = None\n",
    "if llm_config:\n",
    "    try:\n",
    "        sub_question_tool = ReliableTool(\n",
    "            name=\"SubQuestionGenerator\",\n",
    "            func_or_tool=generate_sub_questions_list,\n",
    "            description=\"Reliably generates exactly 3 relevant sub-questions for a given main question.\",\n",
    "            runner_llm_config=llm_config,\n",
    "            validator_llm_config=llm_config,\n",
    "            system_message_addition_for_tool_calling=sub_question_system_message_addition_for_tool_calling,\n",
    "            system_message_addition_for_result_validation=sub_question_system_message_addition_for_result_validation,\n",
    "            max_tool_invocations=5,\n",
    "        )\n",
    "        print(\"Sub Question ReliableTool instance created successfully.\")\n",
    "    except Exception as e:\n",
    "        print(f\"Error creating Sub Question ReliableTool: {e}\")\n",
    "        logger.error(\"Failed to instantiate Sub Question ReliableTool\", exc_info=True)\n",
    "else:\n",
    "    print(\"LLM Configuration not loaded. Cannot create Sub Question ReliableTool.\")\n",
    "\n",
    "grader_system_message_addition_for_tool_calling = \"\"\"You are an AI Evaluator. Assess the provided Sub Question based on its relevance and clarity in the context of the main Question.\n",
    "\n",
    "Assign an integer score (0-100 inclusive) reflecting how well the Sub Question relates to and logically follows from the main Question.\n",
    "- 0 = Completely irrelevant or nonsensical Sub Question.\n",
    "- 100 = Perfectly relevant, clear, and logical Sub Question.\n",
    "\n",
    "Provide a BRIEF justification explaining your score.\n",
    "\n",
    "**Input & Expected Output Examples:**\n",
    "\n",
    "1.  **Input:**\n",
    "    Question: Explain the process of photosynthesis in plants.\n",
    "    Sub Question: What are the primary reactants required for photosynthesis?\n",
    "    **Example Output:**\n",
    "    Score: 100, Justification: \"Directly relevant, clear, and asks about a key component of the main question.\"\n",
    "\n",
    "2.  **Input:**\n",
    "    Question: Discuss the major causes leading to the outbreak of World War II in Europe.\n",
    "    Sub Question: How did the Treaty of Versailles contribute to the tensions?\n",
    "    **Example Output:**\n",
    "    Score: 95, Justification: \"Highly relevant sub-topic that directly addresses a major cause mentioned in the main question.\"\n",
    "\n",
    "3.  **Input:**\n",
    "    Question: Analyze the main themes in George Orwell's \"1984\".\n",
    "    Sub Question: What is the population of London?\n",
    "    **Example Output:**\n",
    "    Score: 10, Justification: \"Sub Question is fact-based but almost entirely irrelevant to analyzing themes in the novel.\"\n",
    "\n",
    "4.  **Input:**\n",
    "    Question: Solve the system: 2x+y=5, x-y=1.\n",
    "    Sub Question: Who was the first US president?\n",
    "    **Example Output:**\n",
    "    Score: 0, Justification: \"Completely irrelevant to the mathematical problem posed in the main question.\"\n",
    "\n",
    "5.  **Input:**\n",
    "    Question: Describe the geography and climate of Brazil.\n",
    "    Sub Question: Talk about cities.\n",
    "    **Example Output:**\n",
    "    Score: 50, Justification: \"Relevant topic (cities are part of geography) but the sub-question is very vague and lacks focus.\"\n",
    "\n",
    "Now, evaluate the provided Sub Question based on the main Question, following this format and reasoning.\"\"\"\n",
    "\n",
    "grader_system_message_addition_for_result_validation = (\n",
    "    \"\"\"Validate that the justification for the grade is clear and relevant.\"\"\"\n",
    ")\n",
    "\n",
    "grade_tool: ReliableTool | None = None\n",
    "if llm_config:\n",
    "    try:\n",
    "        grade_tool = ReliableTool(\n",
    "            name=\"SubQuestionGrader\",\n",
    "            func_or_tool=grade_sub_question,\n",
    "            description=\"Grades a sub question in reference to a task.\",\n",
    "            runner_llm_config=llm_config,\n",
    "            validator_llm_config=llm_config,\n",
    "            system_message_addition_for_tool_calling=grader_system_message_addition_for_tool_calling,\n",
    "            system_message_addition_for_result_validation=grader_system_message_addition_for_result_validation,\n",
    "            max_tool_invocations=5,\n",
    "        )\n",
    "        print(\"Grade ReliableTool instance created successfully.\")\n",
    "    except Exception as e:\n",
    "        print(f\"Error creating Grade ReliableTool: {e}\")\n",
    "        logger.error(\"Failed to instantiate Grade ReliableTool\", exc_info=True)\n",
    "else:\n",
    "    print(\"LLM Configuration not loaded. Cannot create Grade ReliableTool.\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "6",
   "metadata": {},
   "source": [
    "## 3. Get User Input and Run the Tool Synchronously"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"Gets user input and runs the ReliableTool synchronously.\"\"\"\n",
    "\n",
    "main_question = \"How does photosynthesis work in plants?\"  # Example question\n",
    "\n",
    "\n",
    "sub_questions: list[str] | None = sub_question_tool.run(\n",
    "    task=f\"Generate exactly 3 relevant sub-questions for the main question: '{main_question}'\"\n",
    ")\n",
    "\n",
    "graded_sub_questions = []\n",
    "for sub_question in sub_questions:\n",
    "    grade = grade_tool.run(task=f\"Question: {main_question}\\n Sub Question: {sub_question}\")\n",
    "    graded_sub_questions.append((sub_question, grade))\n",
    "\n",
    "\n",
    "logger.info(\"\\n✅ Successfully generated sub-questions:\")\n",
    "for i, (sub_question, grade) in enumerate(graded_sub_questions):\n",
    "    if grade > 50:\n",
    "        logger.info(f\"   {i + 1}. ✅ Grade: {grade} - {sub_question}\")\n",
    "    else:\n",
    "        logger.info(f\"   {i + 1}. ❌ Grade: {grade} - {sub_question}\")"
   ]
  }
 ],
 "metadata": {
  "front_matter": {
   "description": "ReliableTool - Basic Example",
   "tags": [
    "tool calling",
    "tools",
    "reliable"
   ]
  },
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
